
#include <DefineCommon.h>
#include <iostream>
#include <vector>
#include <string>
#include <ClangFunction.h>
#include <cmdline.h>
#include <AutogenCodeGenerator.h>


int handleClassFile( const EString& fileName 
                ,const EString& className 
                ,const EString& includePath
                ,const EString& outPutDir
                )
{
    // std::vector<CppInfo::CppFilePtr> filePtrList; 
    // EStringList fileNames;
    // EStringList classNames;
    // fileNames.push_back(fileName);
    // classNames.push_back(className);

    EStringList includePathList = includePath.split(";");

    // for(int i = 0 ; i < fileNames.size(); i++)
    // {
        CppInfo::CppFilePtr filePtr(new CppInfo::CppFile);
        filePtr->fileName = fileName;
        if(className.isEmpty()==false)
        {
            filePtr->classNameList.push_back(className);
        }
        filePtr->incFilePathList = includePathList;
        // filePtrList.push_back(filePtr);
    // }

    CppInfo::CppCollectionPtr collPtr(new CppInfo::CppCollection);

    // for(int i = 0 ; i < filePtrList.size(); i++ )
    // {
        ClangFunction::fileToCollection(filePtr, collPtr);
    // }
    
    AutogenCodeGeneratorPtr codeGenPtr(new AutogenCodeGenerator);
    codeGenPtr->collectionToFiles(collPtr, outPutDir);

    // ELOG_INFO("collPtr=%s", collPtr->getPrintStr().data());

    return 1;
}

int main(int argc, char *argv[])//
{
    // spdlog::cfg::load_env_levels();

    /*First modeName define wrap code code 
     * generating  or regFunction code generating  
     * for example:
     * -m "wrap osg", for wrap code
     * -m "reg osg", for reg code
     *
     * In wrap code mode,className is a single word.
     * In reg code mode,className is no meaning.
     * For example:
     * -c "osg::Node", for wrap code
     *
     * In wrap code mode, includePath is the dir needed by fileName.
     * In reg code mode, includePath is the ItemWrap_xxx_gen.h 's dir.
     * RegCodeGenerator will iterator the h file in includePath and generate RegFunctionXXX
     *
     */
    cmdline::parser cmdParser;
    cmdParser.add<std::string>("className", 
                                'c', 
                                "Class name in the head file", 
                                false, 
                                "");
    cmdParser.add<std::string>("outPutDir", 
                                'o', 
                                "The path to save wrap class code", 
                                true, 
                                "");
    cmdParser.add<std::string>("fileName", 
                                'f', 
                                "File name of C++ head file", 
                                true, 
                                "");
    cmdParser.add<std::string>("includePath", 
                                'i', 
                                "include path list need by head file, split with \";\"", 
                                false, 
                                "");

    cmdParser.parse_check(argc, argv);
    EString fileName = EString::fromStdString(cmdParser.get<std::string>("fileName"));
    EString className = EString::fromStdString(cmdParser.get<std::string>("className"));
    EString includePath = EString::fromStdString(cmdParser.get<std::string>("includePath"));
    EString outPutDir = EString::fromStdString(cmdParser.get<std::string>("outPutDir"));

    // EString fileName= "/root/EEditor2/source/PluginDefault/EItemInPlugin.h";
    // EString className = "EItemInPlugin";
    // EString includePath = "/root/EEditor2/source/LibCommon";
    // EString outPutDir = "/root/EEditor2/source/PluginDefault/";

     // EString fileName= "PluginDefault/EItemInPlugin.h";
     // EString className = "EItemInPlugin";
     // EString includePath = "LibCommon";
     // EString outPutDir = "PluginDefault/";

    ELOG_INFO("Parameters:\nfileName=\"%s\"\nclassName=\"%s\"\nincludePath=\"%s\"\noutPutDir=\"%s\"\n"
            ,fileName.data()
            ,className.data()
            ,includePath.data()
            ,outPutDir.data());


    handleClassFile(fileName
                    ,className
                    ,includePath
                    ,outPutDir);

    return 1;

}
